今天我會裡用之前所學的 requests
+ BeautifulSoup
+ Selenium
去進行微博的自動化登入
requests
庫來發送請求。首先,創建一個 Session ,將 Cookies 加入到這個 Session 中,然後發送一個 GET 請求去訪問指定的網頁。得到網頁內容後,我們用 BeautifulSoup 來解析 HTML。<script>
標籤。從這個標籤中提取出用戶名,並顯示出來。這樣可以確保在 Cookies 存在的情況下直接進行請求,如果沒有 Cookies 就進行登入操作並保存 Cookies 以便下次使用。
import os
import json
from bs4 import BeautifulSoup
import requests
from selenium import webdriver
from time import sleep
from cookies import CookieLogin
# 配置 Chrome 瀏覽器的選項
prefs = {
'profile.default_content_setting_values': {
'notifications': 2 # 隱藏 chromedriver 的通知
},
'credentials_enable_service': False, # 隱藏 chromedriver 自帶的保存密碼功能
'profile.password_manager_enabled': False # 隱藏 chromedriver 自帶的保存密碼功能
}
options = webdriver.ChromeOptions()
options.add_experimental_option('prefs', prefs)
options.add_experimental_option('excludeSwitches', ['enable-automation']) # 設置為開發者模式,禁用 chrome 正受到自動化檢測的顯示
options.add_argument('--disable-gpu') # google 文檔提到需要加上這個屬性來規避 bug
# 定義 Cookies 文件的名稱
cookie_fname = 'cookie.json'
login = CookieLogin(cookie_fname)
# 檢查是否已保存 Cookies
cookies = login.load_cookies() # 嘗試從文件中加載已保存的 Cookies
if cookies:
print("使用保存的 Cookies 進行請求")
# 使用 requests 進行請求
session = requests.Session() # 創建一個 Session 對象來管理 Cookies
for cookie in cookies:
# 添加每個 cookie 到 requests 的 session 中
session.cookies.set(cookie['name'], cookie['value'], domain=cookie['domain'])
# 發送請求
url = "https://s.weibo.com/weibo?q=%E6%96%B0%E5%86%A0%E7%96%AB%E6%83%85" # 要訪問的 URL
response = session.get(url) # 發送 GET 請求
# 使用 BeautifulSoup 解析頁面內容
soup = BeautifulSoup(response.text, 'html.parser') # 解析 HTML 內容
# 提取用戶名(假設用戶名在頁面的某個特定位置,可以用 BeautifulSoup 查找)
try:
# 假設用戶名在某個特定的 HTML 元素中
user_info = soup.find('script', string=lambda t: t and 'var $CONFIG' in t) # 查找包含 $CONFIG 的 script 標籤
if user_info:
script_content = user_info.string # 獲取 script 標籤的內容
start_index = script_content.find('nick') + 10 # 找到 'nick' 的開始位置
end_index = script_content.find(';', start_index) # 找到 ';' 的位置
nick = script_content[start_index:end_index].strip().strip("'") # 提取用戶名並去除多餘的字符
print(f"用戶名: {nick}")
else:
print("未能找到用戶名")
except Exception as e:
print(f"提取用戶名時出錯: {e}")
else:
print("Cookies 不存在,使用 Selenium 進行登入")
# 使用 Selenium 進行登入
wd = webdriver.Chrome(options=options) # 創建 Chrome WebDriver 對象
url = "https://passport.weibo.com/sso/signin?entry=miniblog&source=miniblog&disp=popup&url=https%3A%2F%2Fweibo.com%2Fnewlogin%3Ftabtype%3Dweibo%26gid%3D102803%26openLoginLayer%3D0%26url%3Dhttp%253A%252F%252Fmcn.weibo.com%252Fintroduce" # 登入頁面 URL
wd.get(url=url) # 打開登入頁面
sleep(20) # 等待 20 秒,讓用戶有時間掃描二維碼進行登入
# 保存 Cookies 到本地
cookies = wd.get_cookies() # 獲取當前的 Cookies
login.save_cookies(cookies) # 保存 Cookies 到文件
wd.close() # 關閉瀏覽器窗口
wd.quit() # 退出 WebDriver 實例,釋放資源
CookieLogin
類的實例,指定 Cookies 文件的保存路徑。save_cookies
方法將 Cookies 數據以 JSON 格式保存到指定文件中。load_cookies
方法從指定文件中讀取 Cookies。import os
import json
class CookieLogin:
def __init__(self, f_path):
# Cookies 文件保存路徑
self.f_path = f_path
def save_cookies(self, data, encoding="utf-8"):
try:
# 嘗試打開指定路徑的文件,以寫入模式打開,並使用指定的編碼
with open(self.f_path, "w", encoding=encoding) as f_w:
# 將 Cookies 資料轉換為 JSON 格式並寫入文件
json.dump(data, f_w)
print("Cookies 保存成功!")
except IOError as e:
print(f"保存 Cookies 時出錯: {e}")
def load_cookies(self, encoding="utf-8"):
# 從文件加載 Cookies
if os.path.isfile(self.f_path):
try:
# 嘗試打開指定路徑的文件,以讀取模式打開,並使用指定的編碼
with open(self.f_path, "r", encoding=encoding) as f_r:
# 從文件中讀取 JSON 格式的 Cookies 數據
user_cookies = json.load(f_r)
return user_cookies
except (IOError, json.JSONDecodeError) as e:
print(f"加載 Cookies 時出錯: {e}")
return []
else:
print("Cookies 文件不存在")
return []